package com.ytf.dogbox.activity;

import static java.lang.Thread.currentThread;

import android.app.Service;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.text.format.Time;


import com.alibaba.fastjson2.JSON;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.qiniu.linking.model.DeviceHistoryListing;
import com.tiwolf.cplusmethodutil.CRCFromCUtil;
import com.tiwolf.cplusmethodutil.HexToByteUtil;
import com.ytf.dogbox.bean.AlarmBean;
import com.ytf.dogbox.bean.DogConfigBean;
import com.ytf.dogbox.bean.DogEventBean;
import com.ytf.dogbox.bean.DogOtherBean;
import com.ytf.dogbox.bean.DogPriceBean;
import com.ytf.dogbox.bean.DogPublishBean;
import com.ytf.dogbox.bean.FlowBean;
import com.ytf.dogbox.bean.FlowMsgBean;
import com.ytf.dogbox.bean.LiveContentBean;
import com.ytf.dogbox.bean.LiveObjBean;
import com.ytf.dogbox.bean.PaySuccessBean;
import com.ytf.dogbox.bean.ReceiverBean;
import com.ytf.dogbox.bean.UpLoadGetBean;
import com.ytf.dogbox.boxState.AmmeterData;
import com.ytf.dogbox.config.SerialConfigUtil;
import com.ytf.dogbox.serialport.ComBean;
import com.ytf.dogbox.serialport.MyFunc;
import com.ytf.dogbox.serialport.SerialHelper;
import com.ytf.dogbox.util.ActivityConfig;
import com.ytf.dogbox.util.FlyTextUtil;
import com.ytf.dogbox.util.HttpUtil;
import com.ytf.dogbox.util.Log;
import com.ytf.dogbox.util.PreferenceUtil;
import com.ytf.dogbox.util.TestConfig;

import net.bytebuddy.description.method.MethodDescription;

import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentLinkedDeque;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;


/**
 * @author tiwolf_li
 * @Date on 2020/1/3
 * @Description 集成了socket和mqtt的长连接
 */
public class SocketService extends Service implements SerialHelper.OnSerialPortReceivedListener{

    private final static String TAG=SocketService.class.getSimpleName();
    public static boolean isQiNiuFlag=true;
    public static boolean isScheduleDoneFlag=true;

    /**
     * 1.摄像头及其相关
     */
    public final static String ACTION_CONN="action.conn.flag";      //连接成功标志
    public final static String ACTION_DISCONN="action.disconn.flag";    //连接失败标志

    public final static String ACTION_MSG="action.msg";     //信息标志
    public final static String ACTION_HEART="action.heart";//心跳信息
    public final static String EXTRA_DATA_FLAG="extra_data_flag";//信息获取标志
    public final static String SERVER_MSG="server_msg";//手机消息
    public final static String SERVER_MSG_FLAG="server_msg_flag";

    public final static String MSG_DN="msg_dn";//关屏
    public final static String MSG_DO="msg_do";//开屏

    public final static String WIND_DIRECTION="wind_direction";
    public final static String WIND_SPEED="wind_speed";

    //    public static final String HOST = "192.168.1.34";//内网
//    public static final String HOST = "113.98.248.11";
    public static final String HOST = "8.129.185.215";
    public static final int PORT = 12345;
    private long HEART_BEAT_RATE=2*1000;

    //专门处理洗狗机下发指令的线程
    private ConcurrentLinkedDeque<String> dogSerialLinkedDeque=new ConcurrentLinkedDeque<>();
    Thread dogSerialThread=null;
    private static Object dogSerialObject=new Object();

    AmmeterData ammeterData;

    ArrayList<String> boardList=new ArrayList<>();
    String[] lessBoards={"cf","cm","ar","ct","cn","cr","co","rb","nt","debug","cl","fm","ch","cd","direct","topic","thirdStream","streamLine","resolution","partCode","upcover",};

    //客户端ID，一般以客户端唯一标识符表示，这里用设备序列号表示

    /**
     * 相关的表  1.主板 2.灯 4.摄像头 8.电池 16.风机 32.屏幕 64.传感器 128.太阳能板 256.扬声器 512.wifi
     */
    int totalInt=0,panelInt=0,ledInt=0,cameraInt=0,powerInt=0,windInt=0,windowInt=0,sensorInt=0,solarInt=0,loudInt=256,wifiInt=0;

    private String deviceSn=null;


    String windStr="";

    //默认是多网口的tty数据
    private String led485serial="/dev/ttyS8";       //环监，路灯，电量 RS485
    private String water485serial="/dev/ttyS7";     //水位监测
    private String angalserial="/dev/ttyS1";        //角度倾斜

    /**
     * 2.MQTT走路灯信息
     */
    private static MqttClient mqttAndroidClient=null;
    private MqttConnectOptions mMqttConnectOptions;

    public String mqttHOST="tcp://"+ TestConfig.HOST +":61613";//服务器地址（协议+地址） 内网
    //    public String userName="admin";//用户名 内网
//    public String password="password";//密码 内网
//    public String mqttHOST="tcp://120.77.211.29:61613";//服务器地址（协议+地址） 外网
    public String userName="admin";//用户名
    public String password="uuB#tuJ^ib4p&S7Dh";//密码
    public static String PUBLISH_TOPIC="test/topic";//发布主题
    public static String RESPONSE_TOPIC="topic/uplink";//响应主题
    public static String WATER_TOPIC="topic/environ";//环境部分的主题

    public static String REC_TOPIC="topic/recognize";//识别部分主题
    public static String DOGBOX_TOPIC="topic/wash";//洗狗机上传机子数据主题
    public static String DOGBOX_CONFIG_TOPIC="topic/wash/config";//洗狗机上传机子配置主题
    public static String DOGBOX_FLOW_TOPIC="topic/wash/process";//洗狗机上传洗狗流程

    public String responseTopics[]={FlyUtil.getSn(this),"INOT",Build.MODEL};
    public int qoss[]={2,2,2};
    ReceiverBean receiverBean=new ReceiverBean();
    Thread busyWorkThread=null;
    Thread statusThread;

    private boolean dogBoxExitFlag=true;//可以作为ondestroy时while循环的更改
    private boolean isFixedVolume=false;




    boolean policeModeFlag=false;

    /**==================往服务器送的信息=======================*/
    String version;
    String mechineVersion;
    String mechineMode;
    String zoneStr;
    double lat,lnt;
    String signal="0";
    String length="0";
    String mechineIp="";
    String doorStr;
    double waterTemInt;
    double invirTemInt;
    int dogboxStateInt=0;
    int dogLeaveTime=0;
    DogPublishBean dogPublishBean;



    int uploadBoardState=30;
    int boardState=21;
    int flowInt=10;
    int temInt=0;
    int angleInt=0;
    int waterInt=0;
    int regularTime=20;
    int weatherInt=5;
    int weatherLedInt=5;
    boolean isback=true;
    int eleType=0;
    //守护线程
    int first=0;//第一次获取这个标志不作为，下一次再操作。避免出现因为延时而出现的问题
    int stateNum=20;//这个主要用来向上发布路灯状态
    private int clientNeedTime=1;
    boolean oneTimes=true;//只配置一次的，串口






    //2021-3-2移到这，如果有问题，则返回333
    Time t=new Time(); // or Time t=new Time("GMT+8"); 加上Time Zone资料。
    //读取当前手机时间
    private String currentTime(){
        String msg="";
        String str1="AA551301";
        String str="0A0D0000000008";
        //返回这里333
//        Time t=new Time(); // or Time t=new Time("GMT+8"); 加上Time Zone资料。
        t.setToNow(); // 取得系统时间。
        int year = t.year;
        int month = t.month+1;
        int date = t.monthDay;
        int hour = t.hour; // 0-23
        int minute = t.minute;
        int second = t.second;
        int week=t.weekDay;

        String yearStr=getSum(year);
        String monthStr= String.format("%02X",month);
        String dateStr= String.format("%02X",date);
        String hourStr= String.format("%02X",hour);
        String minuteStr= String.format("%02X",minute);
        String secondStr= String.format("%02X",second);
        String weekStr= String.format("%02X",week);
        String yearStr1= String.format("%02X",(year-2000));


        msg=str1+yearStr1+monthStr+dateStr+hourStr+minuteStr+secondStr+"B44B";

        return msg;
    }

    //计算数据,将Integer转变成16进制字节码
    private String getSum(int num) {
        String str="";
        if (0==num)
        {
            return null;
        }

        while (num>16)
        {
            int x=num%16;
//            String.format("%X",Double.valueOf(dawnEt.getText().toString()).byteValue());
            String xx= String.format("%X",x);
            num=num/16;
            str=xx+str;
        }
        String xxx= String.format("%X",num);
        str=xxx+str;
        if (str.length()==1)
        {
            str="000"+str;
        }
        else if (str.length()==2)
        {
            str="00"+str;
        }
        else if (str.length()==3)
        {
            str="0"+str;
        }
        return str;
    }


    private String eleVlo;//电表电压
    private String electric;//电表电流
    private String electricity;//电表电量
    private String eleFre;//电表频率



    @Override
    public void onCreate() {
        super.onCreate();
        SingleThreadPool.init();
        Log.e(TAG, "onCreate: 使用单例线程池来处理mqtt收到的数据" );
        deviceSn=FlyUtil.getSn(this);
//        DispQueue = new DispQueueThread();
//        DispQueue.start();

        dogPublishBean=new DogPublishBean();
        ammeterData=new AmmeterData();
        //这个获取外部路径也有可能是耗时操作
        String mechineModel=FlyUtil.getMeChineModel(this);
        if (FlyUtil.smallBoard3568.equals(mechineModel)){
            water485serial="/dev/ttyS4";
            angalserial="/dev/ttyS3";
            led485serial="/dev/ttyS5";
        }


//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep(2000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
////                ttyS0.setPort("/dev/ttyS0");
////                ttyS0.setBaudRate(9600);
////                OpenComPort(ttyS0);
//
//
//            }
//        }).start();

        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        waterSc=new SerialHelper(water485serial,9600);
        waterSc.setSerialPortReceivedListener(this);
        waterSc.openSerial();
        angalSc=new SerialHelper(angalserial,9600);
        angalSc.setSerialPortReceivedListener(this);
        angalSc.openSerial();
        ledSc=new SerialHelper(led485serial,9600);
        ledSc.setSerialPortReceivedListener(this);
        ledSc.openSerial();
//        waterSc.setPort(water485serial);
//        waterSc.setBaudRate(9600);
//        OpenComPort(waterSc);
//        angalSc.setPort(angalserial);        //3288对应的是angalSc，3568对应的是ttyS5
//        angalSc.setBaudRate(9600);
//        OpenComPort(angalSc);
//        ledSc.setPort(led485serial);        //3288对应的是ledSc，3568对应的是ttyS8
//        ledSc.setBaudRate(9600);
//        OpenComPort(ledSc);

        busyWorkThread=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                while (busy){
                    busyWork("00001");
                    try {
                        Thread.sleep(6000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        });
        init();
        busyWorkThread.start();

        startDogSerialThread();
        dogBoxStatus();

    }

    int sendOrderInt=0;
    private void startDogSerialThread(){
        dogSerialThread=new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.interrupted()) {
                    while (!dogSerialLinkedDeque.isEmpty()) {
                        String order = dogSerialLinkedDeque.poll();
                        if (waterSc!=null){
                            sendOrderInt=0;
                            sendPortData(waterSc,order);
                            while (sendOrderInt<5){
                                sendOrderInt++;     //每次发完指令，都会等待2.5秒。如果没有返回，则下发下一条数据
                                try {
                                    Thread.sleep(300);
                                } catch (InterruptedException e) {
                                    throw new RuntimeException(e);
                                }
                            }
//                            Log.e(TAG, "run: 下发指令=====为="+order);
                        }
                    }

                    //Waiting for next file
                    synchronized (dogSerialObject) {
                        try {
                            //isEmpty() may take some time,so we set timeout to detect next file
                            dogSerialObject.wait(200);
                        } catch (InterruptedException e) {
//                        e.printStackTrace();
                            dogSerialThread.interrupt();
                        }
                    }

                }


            }
        });
        dogSerialThread.setPriority(10);
        dogSerialThread.start();
    }


    private void dogBoxStatus(){
        //当前线程用来一直检测洗狗机状态
        statusThread=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                while(dogBoxExitFlag){

//                    if (waterSc!=null){
//                        sendPortData(waterSc, SerialConfigUtil.CONFIGDOGBOXSTATUS);
//                    }
                    dogSerialLinkedDeque.add(SerialConfigUtil.CONFIGDOGBOXSTATUS2);
                    synchronized (dogSerialObject) {
                        dogSerialObject.notifyAll();
                    }

                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }

            }
        });
        statusThread.start();
    }


    /**===================从activity发送指令过来======================*/
    public void sendMechineOrder(String sOut){
//        if (waterSc!=null){
//            sendPortData(waterSc,sOut);
//        }
        if (dogSerialLinkedDeque!=null){
            dogSerialLinkedDeque.add(sOut);
            synchronized (dogSerialObject) {
                dogSerialObject.notifyAll();
            }
        }

    }

    //这个在紧急停止的时候，需要先将之前要下发的指令先清空
    public void clearSerialList(){
        Log.e(TAG, "run: 对指令进行清除");
        if (dogSerialLinkedDeque!=null && dogSerialLinkedDeque.isEmpty()){
            Log.e(TAG, "run: 在这里对指令进行清除");
            dogSerialLinkedDeque.clear();
        }
    }
    /**
     * GPS数据
     * @param lat 经度
     * @param lnt 纬度
     */
    public void sendMechineGps(double lat,double lnt){
        this.lat=lat;
        this.lnt=lnt;
    }

    /**
     *
     * @param signalStr 包括网络类型，强度
     */
    public void signalValue(String signalStr){
        if ("0".equals(signalStr)){
            //无网络
            signal="0";
            length="0";
        }else if (signalStr.length()>1 && signalStr.startsWith("1")){
            //wifi
            //signal.substring(1)这个是wifi信号强度
            signal="1";
            length=signalStr.substring(1);
        }else if(signalStr.length()>1 && signalStr.startsWith("2")){
            //2G
            //signal.substring(1)这个是2G信号强度
            signal="2";
            length=signalStr.substring(1);
        }else if(signalStr.length()>1 && signalStr.startsWith("4")){
            //4G
            //signal.substring(1)这个是4G信号强度
            signal="4";
            length=signalStr.substring(1);
        }else if("line".equals(signalStr)){
            signal="5";
            length="0";
        }

    }

    /**
     *
     * @param boxIp  设备的ip
     * @param mechineMode   洗狗机设备型号
     * @param appVersion    洗狗机APP版本
     * @param broadVersion  洗狗硬件版本
     */
    public void sendIpAndVersion(String boxIp, String mechineMode,String appVersion,String broadVersion){
        this.mechineIp=boxIp;
        this.version=appVersion;
        this.mechineVersion=broadVersion;
        this.mechineMode=mechineMode;
        zoneStr=TimeZone.getDefault().getID();
//        android.util.Log.e(TAG, "sendIpAndVersion: 时区=="+TimeZone.getDefault().getDisplayName() );
    }

    /**===================从activity发送指令过来--end======================*/


    boolean busy=true;
    boolean sensorSend=false;
    //这个方法每次运行需要差不多1.3s左右，大概以数据估计
    private void busyWork(String work){
        switch (work){
            case "00001":{
//                Log.i(TAG, "busyWork publish run55555: "+currentThread().getName()+",状态="+mqttSendFlag +";stateNum="+stateNum);
                //检查之前mqtt是否无法进行设置setwill
                if (!doConnect){
                    initMqttSetWill();
                }


                Log.i(TAG, "busyWork run: 空间数据="+ boardState);
                if (boardState==0){
                    //等于0的时候，去获取洗狗机实时数据
                    if (iServiceToActivity!=null){
                        iServiceToActivity.sendMsgToActivity(ActivityConfig.DOGBOXSTATEINFOFLAG,null);
                    }
                }
                //每隔三分钟上传一次洗狗机基础数据
                if (boardState<0){
                    boardState=uploadBoardState;
                    //开始上传洗狗机数据
                    if (dogPublishBean==null){
                        dogPublishBean=new DogPublishBean();
                    }
                    dogPublishBean.setAppVersion(version);
                    dogPublishBean.setBoardModel(mechineMode);
                    dogPublishBean.setInotVersion(mechineVersion);
                    dogPublishBean.setIp(mechineIp);
                    if (lat!=0){
                        dogPublishBean.setLat(""+lat);
                        dogPublishBean.setLng(""+lnt);
                    }
                    dogPublishBean.setNetType(signal);
                    dogPublishBean.setNetst(length);
                    dogPublishBean.setRoomTemp(""+invirTemInt);
                    dogPublishBean.setTemp(""+waterTemInt);
                    dogPublishBean.setDoorStatus(doorStr);
                    dogPublishBean.setTimeZone(zoneStr);
                    dogPublishBean.setSn(FlyUtil.getSn(SocketService.this));
                    dogPublishBean.setWashState(dogboxStateInt);
                    dogPublishBean.setRemainTime(dogLeaveTime);
                    dogPublishBean.setUpTime(DateUtil.now());

                    String dogstr= com.alibaba.fastjson2.JSONObject.toJSONString(dogPublishBean);
//                    cn.hutool.json.JSONObject jsonObject=JSONUtil.parseObj(dogPublishBean,true);
                    Log.e(TAG, "busyWork: 洗狗机需要上传的值为="+dogstr );
                    publishMsg(DOGBOX_TOPIC,dogstr);
                }
                boardState--;


                break;
            }
        }
    }

    /**
     * 往上传洗狗机的配置参数
     * @param dogConfigBean
     */
    public void publishDogConfig(DogConfigBean dogConfigBean){
        String dogConfigstr= com.alibaba.fastjson2.JSONObject.toJSONString(dogConfigBean);
        publishMsg(DOGBOX_CONFIG_TOPIC,dogConfigstr);
    }

    public void publishDogFlow(FlowMsgBean flowMsgBean){
        String flowMsgStr= com.alibaba.fastjson2.JSONObject.toJSONString(flowMsgBean);
        publishMsg(DOGBOX_FLOW_TOPIC,flowMsgStr);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private final IBinder mBinder = new LocalBinder();


    private String getDay(){
        Calendar cal = Calendar.getInstance();
//        cal.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));

        String year = String.valueOf(cal.get(Calendar.YEAR));
        String month = String.valueOf((cal.get(Calendar.MONTH)+1));
        String day = String.valueOf(cal.get(Calendar.DATE));
        return year+"-"+month+"-"+day;
    }


    @Override
    public void onSerialPortDataReceived(ComBean comRecData) {
        Log.e(TAG, "onSerialPortDataReceived: 处理接收到的串口消息" );
        DispRecData(comRecData);
    }


    public class LocalBinder extends Binder{
        public SocketService getService(){
            return SocketService.this;
        }
    }






    boolean doConnect=false;

    private void init() {
//        String serverURI=mqttHOST;//服务器地址（协议+地址+端口号）
//        mqttAndroidClient=new MqttAndroidClient(getApplicationContext(),serverURI,FlyUtil.getSn(this));
        try {
            mqttAndroidClient=new MqttClient(mqttHOST,FlyUtil.getSn(this),new MemoryPersistence());
        } catch (MqttException e) {
            e.printStackTrace();
        }
        mqttAndroidClient.setCallback(mqttCallbackExtended);//设置监听订阅消息的回调
//        mqttAndroidClient.registerResources(getApplicationContext());
        mMqttConnectOptions=new MqttConnectOptions();
        mMqttConnectOptions.setCleanSession(true);//设置是否清除缓存
//        mMqttConnectOptions.setConnectionTimeout(10);//设置超时时间，单位：秒
        mMqttConnectOptions.setKeepAliveInterval(100);//设置心跳包发送间隔，单位：秒
        mMqttConnectOptions.setMaxInflight(100);//支持同时发送的消息数为100（默认为10）
        mMqttConnectOptions.setUserName(userName);//设置用户名
        mMqttConnectOptions.setPassword(password.toCharArray());//设置密码
        // 设置当与服务端失去连接时自动重连服务端，默认为false
//        mMqttConnectOptions.setAutomaticReconnect(true);




    }

    private synchronized void initMqttSetWill(){
        //last will message

        String message="";
        String topic=RESPONSE_TOPIC;
        Integer qos=2;
        Boolean retained=false;
//        if ((!message.equals("")) || (!topic.equals(""))){
        if ((!topic.equals(""))){
            //最后的遗嘱
            try {
                mMqttConnectOptions.setWill(topic,message.getBytes(),qos.intValue(),retained.booleanValue());
                doConnect=true;
                Log.i(TAG, "mqtt设备 配置好遗嘱" );
            }catch (Exception e){
                Log.i(TAG, "mqtt设备配置遗嘱的时候出现异常="+e.getMessage());
                doConnect=false;
                iMqttActionListener.onFailure(null,e);
            }
        }

        Log.i(TAG, "subscribeTopic: mqtt设备去连接mqtt服务器+=="+doConnect);
        if (doConnect){
            doClientConnection();
        }
    }


    boolean mqttSendFlag=false;
    /**
     * 类型添加：数据类型:1.主板 2.灯 4.摄像头 8.电池 16.风机 32.屏幕 64.传感器 128.太阳能板 256.扬声器 512.wifi
     * @param message
     * {"wv":"0.00","wc":"0.00","ws":"0","sv":"0.00","sc":"0.00","bv":"11.74","bp":"72","bt":"26","os":"0"}
     */
    public synchronized void publish(String message,int sensor){
//        Log.i(TAG, "publish:上传数值标志="+isNetWork );
        if (!isNetWork)return;
        mqttSendFlag=true;
        String topic=RESPONSE_TOPIC;
        Integer qos=2;
        Boolean retained=false;
        String str = null;
        //有人流数据，所以摄像头一直会有数据
        cameraInt=4;
        JSONObject updateJson=null;
        if ("2".equals(message)){
            //这里处理的是运营数据
            updateJson=new JSONObject();
            try {
                updateJson.put("dt","2");
                updateJson.put("tm",getDay());
                updateJson.put("elc",electric);
                updateJson.put("elq",electricity);
                updateJson.put("elt",eleVlo);
                updateJson.put("elr",eleFre);
                updateJson.put("sn",FlyUtil.getSn(this));
                str=updateJson.toString();
                Log.i(TAG, "publish: 流量数值为="+str );
            } catch (JSONException e) {
                e.printStackTrace();
            }


        }else{
//            Log.i(TAG, "publish: 仅有主板数据的情况下0000" );
            if (message.contains(FlyUtil.getSn(this))){
                str=message;
            }else if("1".equals(message)){
                //这条是在message没数据的情况下的，还有一个是message没有数据
//                Log.i(TAG, "publish: 仅有主板数据的情况下11111111111" );
                panelInt=1;
                loudInt=256;
                totalInt=panelInt+ledInt+cameraInt+powerInt+windInt+windowInt+sensorInt+solarInt+loudInt+wifiInt;
                String bi=Integer.toBinaryString(totalInt);
                int biInt=Integer.parseInt(bi);
                String biStr=String.format("%010d",biInt); //前面补0
//            Log.i(TAG, "publish这个是dt: "+biStr);

                //添加当前媒体声音值
                AudioManager audio= (AudioManager) getSystemService(AUDIO_SERVICE);
                int musicVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC);
                int musicMaxVolume=audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);


//            Log.i(TAG, "publish:最大的音量值 "+musicMaxVolume );
//            Log.i(TAG, "publish: 最小的音量值"+musicMinVolume );

                updateJson=new JSONObject();
                try {

                    updateJson.put("ss",signal);
                    updateJson.put("bs",length);
                    updateJson.put("ve",version);
                    updateJson.put("hv",mechineVersion);
                    updateJson.put("y9",Build.MODEL);




                    updateJson.put("dt",biStr);
                    updateJson.put("av",musicVolume);
                    updateJson.put("sn",FlyUtil.getSn(this));
                    str=updateJson.toString();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
//            str=updateJson.toString();

//            //2020.2.17添加gps ln和lat。观察是否有问题
//            str="{\"ss\":\""+signal+"\",\"bs\":\""+length+"\",\"z6\":\""+man+"\"";
//            if (TimeZoneUtil.getTimeZone()!=null){
//                str=str+",\"tw\":\""+ TimeZoneUtil.getTimeZone();
//            }
//
//            if (lat!=null && ln!=null){
//                str=str+"\",\"la\":\""+lat+"\",\"ln\":\""+ln;
//            }
//            str=str+"\",\"dt\":\""+biStr+"\",\"av\":\""+musicVolume;
//            str=str+"\",\"sn\":\""+CLIENTID+"\"}";
            } else {
                //这条是在message有数据的情况下的，还有一个是message没有数据
                Log.i(TAG, "publish: 在message有数据的情况下" );
                panelInt=1;
                loudInt=256;
                totalInt=panelInt+ledInt+cameraInt+powerInt+windInt+windowInt+sensorInt+solarInt+loudInt+wifiInt;
                String bi=Integer.toBinaryString(totalInt);
                int biInt=Integer.parseInt(bi);
                String biStr=String.format("%010d",biInt); //前面补0
//            Log.i(TAG, "publish这个是dt: "+biStr);

                //添加当前媒体声音值
                AudioManager audio= (AudioManager) getSystemService(AUDIO_SERVICE);
                int musicVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC);
                int musicMaxVolume=audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
//            Log.i(TAG, "publish:最大的音量值 "+musicMaxVolume );
//            Log.i(TAG, "publish: 最小的音量值"+musicMinVolume );

                try {
                    //这个是已经获取到传感器数据的
                    updateJson=new JSONObject(message);
                    updateJson.put("ss",signal);
                    updateJson.put("bs",length);
                    updateJson.put("ve",version);
                    updateJson.put("hv",mechineVersion);
                    updateJson.put("y9",Build.MODEL);


                    updateJson.put("dt",biStr);
                    updateJson.put("av",musicVolume);
                    updateJson.put("sn",FlyUtil.getSn(this));
                    str=updateJson.toString();
                    Log.i(TAG, "publish: 上传的一条数据="+str);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }

        }




        try {
            if (mqttAndroidClient!=null && str!=null && str.length()!=0 && !topic.equals("")){
                Log.i(TAG, "mqtt publish: "+str.getBytes() );
                Log.i(TAG, "mqtt publish: "+qos.intValue() );
                Log.i(TAG, "mqtt publish: "+retained.booleanValue() );
                Log.i(TAG, "mqtt publish: "+topic );
                mqttAndroidClient.publish(topic,str.getBytes(),qos.intValue(),retained.booleanValue());
                Log.i(TAG, "传感器数据 mqtt publish: "+str);
            }


        }catch (MqttException e){
            e.printStackTrace();
            sensorSend=false;
        }


        totalInt=0;
        panelInt=0;     //主板
        ledInt=0;       //灯
        cameraInt=0;    //摄像头
        powerInt=0;     //电池
        windInt=0;      //风机
        windowInt=0;    //屏幕
        sensorInt=0;    //传感器
        solarInt=0;     //太阳板
        loudInt=0;      //声音
        wifiInt=0;      //热点


        mqttSendFlag=false;

    }

    /**
     *
     * @param topic 上报的主题
     * @param msg  需要发送的信息
     */
    private synchronized void publishMsg(String topic,String msg){
        if (!isNetWork)return;

        Integer qos=2;
        Boolean retained=false;

        try {
            if (mqttAndroidClient!=null && msg!=null && msg.length()!=0 && !topic.equals("")){
                Log.i(TAG, "mqtt publish: "+msg);
                Log.i(TAG, "mqtt publish: "+qos.intValue() );
                Log.i(TAG, "mqtt publish: "+retained.booleanValue() );
                Log.i(TAG, "mqtt publish: "+topic );
                mqttAndroidClient.publish(topic,msg.getBytes(),qos.intValue(),retained.booleanValue());
                Log.i(TAG, "已经往上上报数据 ");
            }
        }catch (MqttException e){
            e.printStackTrace();
        }
    }

    private synchronized String getWaterJson(int water){
        if (waterMap==null)
            waterMap=new HashMap<>();
        waterMap.put("sn",FlyUtil.getSn(SocketService.this));
        waterMap.put("dt","1");
        waterMap.put("wl",""+water);
        JSONObject json=new JSONObject(waterMap);
        return json.toString();
    }

    /**
     * 订阅主题回调
     */
    private MqttCallback mqttCallback=new MqttCallback() {
        @Override
        public void connectionLost(Throwable cause) {
            Log.i(TAG, "connectionLost: mqtt设备断开了出现的异常="+cause.getMessage());
//            Log.i(TAG, "subscribeTopic: mqtt设备去订阅流媒体服务器+==;"+isConnecting);
//            if (!isConnecting){
//                doClientConnection();
//            }
            isConnectMqtt=false;
        }

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            String mqttMsg=new String(message.getPayload());
            Log.i(TAG, "messageArrived: mqtt设备收到消息"+mqttMsg);
            //主线程
//            broadcastUpdate(SERVER_MSG,SERVER_MSG_FLAG,"03"+new String(message.getPayload()));

            SingleThreadPool.execute(mqttReceiveRunnable.receiveMqttMsg(mqttMsg));


        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
            Log.i(TAG, "deliveryComplete: mqtt设备消息发送成功时回调的token为="+token.toString());
        }
    };

    private MqttCallbackExtended mqttCallbackExtended=new MqttCallbackExtended() {
        @Override
        public void connectComplete(boolean reconnect, String serverURI) {
            Log.i(TAG, "connectComplete: mqtt设备重连="+reconnect+";服务的地址为="+serverURI);
            if (reconnect){
                //需要重新订阅主题
                Log.i(TAG, "connectComplete: mqtt设备重连后需要订阅主题");
            }
        }

        @Override
        public void connectionLost(Throwable cause) {

            Log.i(TAG, "connectionLost: mqtt设备断开了="+cause.getMessage());

            isConnectMqtt=false;
        }

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            String mqttMsg=new String(message.getPayload());
            Log.i(TAG, "messageArrived: mqtt设备收到消息topic为="+topic+";消息为="+mqttMsg);
            //主线程
//            broadcastUpdate(SERVER_MSG,SERVER_MSG_FLAG,"03"+new String(message.getPayload()));

            SingleThreadPool.execute(mqttReceiveRunnable.receiveMqttMsg(mqttMsg));
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
            Log.i(TAG, "deliveryComplete: mqtt设备消息发送成功时回调的token为="+token.toString());
        }
    };

    MqttReceiveRunnable mqttReceiveRunnable=new MqttReceiveRunnable() {
        private String message;
        @Override
        public MqttReceiveRunnable receiveMqttMsg(String message) {
            this.message=message;
            return this;
        }

        @Override
        public void run() {
            //进行收到的mqtt数据处理
            Log.i(TAG, "runccccc: "+currentThread().getName() );
//            Toast.makeText(getApplicationContext(),"messageArrived:"+new String(message.getPayload()),Toast.LENGTH_SHORT).show();
            //cf-topic-private/intefly/cn/gd/ba/fy/test/3GKL2DZYQQ-

            try {
//                String receiver=new String(message.getPayload());

                JSONObject jsonObject=new JSONObject(message);

                receiverBean.setSn(jsonObject.optString("sn"));
                receiverBean.setOptCode(jsonObject.optString("optCode"));
                receiverBean.setAttrCode(jsonObject.optString("attrCode"));
                receiverBean.setValue(jsonObject.optString("value"));
                receiverBean.setEndUser(jsonObject.optString("endUser"));
                receiverBean.setPartId(jsonObject.optString("partId"));
                receiverBean.setSendTime(jsonObject.optString("sendTime"));
                int vol=jsonObject.optInt("volume");
                receiverBean.setVolume(vol);



                //java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
                //配置命令
                if ("cf".equals(receiverBean.getOptCode())){


                    //配置订阅指令
                    if ("topic".equals(receiverBean.getAttrCode())){
                        String serverTopic=receiverBean.getValue();
                        String[] serverTopics=serverTopic.split("/");
                        subscribeTopic(serverTopics,serverTopic);
//                                if (sdPath==null || sdPath.length()==0){
                        FlyTextUtil.writeTxtFile(receiverBean.getValue(),FlyTextUtil.SDPATH+FlyTextUtil.TXTDIR,FlyTextUtil.SUBMQTT);
                        PreferenceUtil.commitString(PreferenceUtil.DEVICESN,FlyUtil.getSn(SocketService.this));
//                                }else {
//                                    FlyTextUtil.writeTxtFile(receiverBean.getValue(),sdPath+FlyTextUtil.TXTDIR,FlyTextUtil.SUBMQTT);
//                                }
//                                FlyTextUtil.writeTxtFile(receiverBean.getValue(),FlyTextUtil.SDPATH+FlyTextUtil.TXTDIR,FlyTextUtil.SUBMQTT);
                    }else if("palyConf".equals(receiverBean.getAttrCode())){

                        getAdvert(receiverBean.getValue(),jsonObject.optString("time"));

                    }else if("language".equals(receiverBean.getAttrCode())){
                        //决定了app语言的设置
                        Log.i(TAG, "run: 语言切换"+receiverBean.getValue() );
//                                broadcastUpdate(SERVER_MSG,SERVER_MSG_FLAG,"lg"+receiverBean.getValue());
                        sendContent(ActivityConfig.language,receiverBean.getValue());

                    }else if("advert".equals(receiverBean.getAttrCode())){

                        //下载文件
                        Log.i(TAG, "messageArrived: "+receiverBean.getValue() );
                        //需要解析和主界面操作的，全部发过去。让主界面进行处理
                        sendContent(ActivityConfig.advertdownload,receiverBean.getValue());
                    }else if(ActivityConfig.sclive.equals(receiverBean.getAttrCode())){
                        Log.i(TAG, "直播: "+receiverBean.getValue() );
                        String uptime=jsonObject.optString("time");
                        PreferenceUtil.commitString(PreferenceUtil.SYNCLIVE,uptime);
                        LiveObjBean<List<LiveContentBean>> liveObjBean=new Gson().fromJson(receiverBean.getValue(),new TypeToken<LiveObjBean<List<LiveContentBean>>>(){}.getType());
                        if (iServiceToActivity!=null){
                            iServiceToActivity.sendMsgToActivity(ActivityConfig.sclive,liveObjBean);
                        }
                    }else if("partCode".equals(receiverBean.getAttrCode())){
                        //下载文件
                        Log.i(TAG, "功能码配置: "+receiverBean.getValue() );
                        sendContent(ActivityConfig.partcode,receiverBean.getValue());
                    }
                } else if ("wcf".equals(receiverBean.getOptCode())){

                    if ("washType".equals(receiverBean.getAttrCode())){
                        //这个是洗狗机特有的配置功能
                        String uptime=receiverBean.getSendTime();
                        List<DogPriceBean> dogPriceBeanList=new Gson().fromJson(receiverBean.getValue(),new TypeToken<List<DogPriceBean>>(){}.getType());
                        if (iServiceToActivity!=null){
                            iServiceToActivity.sendMsgToActivity(ActivityConfig.DOGBOXCONFIG,dogPriceBeanList,uptime);
                        }
                    }else if ("washStep".equals(receiverBean.getAttrCode())){
                        String uptime=receiverBean.getSendTime();
                        FlowBean flowBean=new Gson().fromJson(receiverBean.getValue(),new TypeToken<FlowBean>(){}.getType());
                        if (iServiceToActivity!=null){
                            iServiceToActivity.sendMsgToActivity(ActivityConfig.DOGBOXFLOWCONFIG,flowBean,uptime);
                        }
                    }else if ("attrConfig".equals(receiverBean.getAttrCode())){
                        String uptime=receiverBean.getSendTime();
                        DogOtherBean dogOtherBean=new Gson().fromJson(receiverBean.getValue(),new TypeToken<DogOtherBean>(){}.getType());
                        if (iServiceToActivity!=null){
                            iServiceToActivity.sendMsgToActivity(ActivityConfig.DOGBOXOTHERCONFIG,dogOtherBean,uptime);
                        }
                    }else if("washOrder".equals(receiverBean.getAttrCode())){
                        String order=receiverBean.getValue();
                        sendMechineOrder(order);
                    }else if ("closePop".equals(receiverBean.getAttrCode())){
                        sendContent(ActivityConfig.DOGCANCELPOP,null);
                    }



                }else if("pay".equals(receiverBean.getOptCode())){
                    String value=receiverBean.getValue();
                    PaySuccessBean paySuccessBean=new Gson().fromJson(value,new TypeToken<PaySuccessBean>(){}.getType());
                    if (iServiceToActivity!=null){
                        iServiceToActivity.sendMsgToActivity(ActivityConfig.PAYSUCCESS,paySuccessBean);
                    }

                }else if("upcover".equals(receiverBean.getOptCode())){
                    String value=receiverBean.getValue();
                    //{"optCode":"upcover","value":"20230523"}
                    //{"optCode":"upcover","value":"2023052311"}
                    if (value!=null){
                        sendContent(ActivityConfig.chpic,value);
                    }

                }else if("cr".equals(receiverBean.getOptCode())){

                    if (iServiceToActivity!=null){
                        iServiceToActivity.sendMsgToActivity(ActivityConfig.cr,"1");
                    }

                }else if("ct".equals(receiverBean.getOptCode())){
                    //实时监控画面关闭
                    if (iServiceToActivity!=null){
                        iServiceToActivity.sendMsgToActivity(ActivityConfig.ct,"1");
                    }

                }else if ("co".equals(receiverBean.getOptCode())){
                    //{"endUser":"CAPPC","optCode":"co","value":{"action":"up","panspeed":5,"tiltspeed":7}}
                    //摄像头 云台控制
                    JSONObject jsonObject1=new JSONObject(receiverBean.getValue());
                    String order=jsonObject1.optString("action");

                    if (iServiceToActivity!=null){
                        //我们研发摄像头
                        Log.i(TAG, "run: 进入非迈特摄像头");
                        if (ActivityConfig.orbitautoon.contains(order)){
                            //说明是启动自动巡视功能
                            String interval=jsonObject1.optString("interval");
                            iServiceToActivity.sendMsgToActivity(order,interval);
                        }else{
                            iServiceToActivity.sendMsgToActivity(order,"0");
                        }
                    }


                }//通知指令
                else if("nt".equals(receiverBean.getOptCode())){
                    //升级  {"optCode":"nt","attrCode":"upgrade","partId":"INOT","value":"1.0.1"}
                    String version=receiverBean.getValue();
                    sendContent(ActivityConfig.nt,version);
                }
                //确认已经下载完了之后，进行手动升级
                else if(ActivityConfig.upapk.equals(receiverBean.getOptCode())){
                    //升级  {"optCode":"upapk","attrCode":"upgrade","partId":"INOT","value":"cat /storage/emulated/0/version/intefly.apk| pm install -S 71718270"}
                    String cmd=receiverBean.getValue();
                    sendContent(ActivityConfig.upapk,cmd);
                }

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    };







    /**
     * 2019年11月06号添加
     * 获取到主题后重新订阅
     * 需要定两个主题
     * @param receiveTops
     */
    private void subscribeTopic(String[] receiveTops,String lastOne){

        /**
         * 订一个主题
         * private/intefly/cn/gd/sz/ba/fy/test/CN20191100003
         */
        /**
         * 订两个主题
         * private/intefly/cn/gd/sz/ba/fy/test/CN20191100003
         * public/cn/gd/sz/ba/fy/test/CN20191100003
         */

        /**
         *  订阅两个主题加 "INOT"和"INOT01";
         */
        String topics="";
        String[] newtopics=new String[receiveTops.length*2];
        int[] newposs=new int[receiveTops.length*2];
        newtopics[0]=FlyUtil.getSn(this);
        newposs[0]=2;
        for (int i = 1; i < receiveTops.length; i++) {

            if (i==1){
                topics=receiveTops[i-1];
            }else {
                topics=topics+"/"+receiveTops[i-1];
                newtopics[i-1]=topics;
                newposs[i-1]=2;
            }
//            Log.i("tiwolf", "subscribeTopic: topics=="+topics );
//            Log.i("tiwolf", "subscribeTopic: newtopics["+(i-1)+"]"+newtopics[i-1]);


        }

        newtopics[receiveTops.length-1]=lastOne;
        newposs[receiveTops.length-1]=2;
//        Log.i("tiwolf", "subscribeTopic: newtopics["+(8)+"]"+newtopics[8]);

        String publictopic="public";
        for (int i = 0; i < receiveTops.length-2; i++) {

            publictopic=publictopic+"/"+receiveTops[i+2];
            newtopics[receiveTops.length+i]=publictopic;
            newposs[receiveTops.length+i]=2;

//            Log.i("tiwolf", "subscribeTopic: newtopics["+(receiveTops.length+i)+"]"+newtopics[receiveTops.length+i] );
        }

        newtopics[receiveTops.length*2-2]="INOT";
        newposs[receiveTops.length*2-2]=2;
//        newtopics[receiveTops.length*2-1]="INOT01";
//        Log.i(TAG, "型号: "+Build.MODEL );
        newtopics[receiveTops.length*2-1]= Build.MODEL;
        newposs[receiveTops.length*2-1]=2;

        try {
            mqttAndroidClient.subscribe(newtopics,newposs);
            Log.i(TAG, "subscribeTopic: 设备订阅服务器成功");
        } catch (MqttException e) {
            e.printStackTrace();
            Log.i(TAG, "subscribeTopic: 设备订阅服务器出问题---"+e.getMessage());
        }
    }

    boolean isNetWork=false;
    boolean isConnectMqtt=false;
    boolean isConnecting=false;
    boolean conMqttFlag=true;
    /**
     * 连接MQTT服务器
     */
    private synchronized void doClientConnection() {
//        isConnecting=true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "run: mqtt设备进来连接");
                while (conMqttFlag){
                    connectMqttServer();
                }

            }
        }).start();
//        isConnecting=false;
    }

    private void connectMqttServer(){
//        isNetWork=HttpUtil.ping();
        isNetWork= HttpUtil.ping();  //这个是耗时操作，先判断之前的两个
        Log.i(TAG, "doClientConnection: mqtt设备连接前判断="+mqttAndroidClient.isConnected()+";是否有网络="+isNetWork+";监听判断的Flag="+isConnectMqtt);
        if (iServiceToActivity!=null){
            if (isNetWork){
                //只有能连上api.intefly.cn和mqtt的才算是联网
                iServiceToActivity.showNetworkState(true);
            }else{
                iServiceToActivity.showNetworkState(false);
            }

        }
        if ((!mqttAndroidClient.isConnected() || !isConnectMqtt) && isNetWork){

//            if (isNetWork){
                Log.i(TAG, "doClientConnection: mqtt设备开始连接");
                try {
                    Thread.sleep(3000);
//                    IMqttToken token=mqttAndroidClient.connect(mMqttConnectOptions,null,iMqttActionListener);
                    mqttAndroidClient.connect(mMqttConnectOptions);
//                IMqttToken token=mqttAndroidClient.connect(mMqttConnectOptions);
                    Log.i(TAG, "doClientConnection: 2-mqtt设备连接了之后得到的数据");
                    isConnectMqtt=true;
                    String deviceSn=PreferenceUtil.getString(PreferenceUtil.DEVICESN,"intefly");
                    String txtStr=FlyTextUtil.readFile(FlyTextUtil.SDPATH,FlyTextUtil.SUBMQTT);
                    Log.e(TAG, "onSuccess: mqtt设备订阅的内容为="+txtStr);
                    //如果sn号和设备之前的号码一样，则去判断有没有订阅文本。不然直接订阅一次，这样子避免设备sn重新烧录不一样号码的时候出现因为有文本不订阅的情况
                    if ((deviceSn==null?FlyUtil.getSn(SocketService.this):deviceSn).equals(deviceSn) && txtStr.length()>7 && txtStr.substring(0,7).equals("private") ){
                        String[] serverTopics=txtStr.split("/");
                        subscribeTopic(serverTopics,txtStr);
                    }else {
                        mqttAndroidClient.subscribe(responseTopics,qoss);
                        Log.i(TAG, "onSuccess: mqtt设备订阅成功之后，上传一条信息" );
                        //如果没有相关订阅消息，则提醒服务器给一条
                        String topic=RESPONSE_TOPIC;
                        Integer qos=2;
                        Boolean retained=false;
                        mqttAndroidClient.publish(topic,FlyUtil.getSn(SocketService.this).getBytes(),qos.intValue(),retained.booleanValue());
                        Log.i(TAG, "onSuccess: mqtt设备上传信息之后" );
                    }
//                token.waitForCompletion();
                    Log.i(TAG, "doClientConnection: 2-mqtt设备连接token连接成功之后");
                } catch (MqttException e) {
                    e.printStackTrace();
                    Log.i(TAG, "doClientConnection: 3-mqtt设备连接异常="+e.getMessage());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    if (isNetWork && isConnectMqtt){
                        //只有能连上api.intefly.cn和mqtt的才算是联网
                        iServiceToActivity.showNetworkState(true);
                    }else{
                        iServiceToActivity.showNetworkState(false);
                    }
                }
//            }

        }
        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        doClientConnection();
    }



    Boolean isOnlyOneDo=true;//mqtt连接成功之后进行一次数据同步
    /**
     * 监听mqtt当前的连接状况
     */
    private IMqttActionListener iMqttActionListener=new IMqttActionListener() {
        @Override
        public void onSuccess(IMqttToken asyncActionToken) {
            Log.i(TAG, "mqtt设备连接成功" );
            isConnectMqtt=true;
            try {
//                String txtStr;
//                if (sdPath==null || sdPath.length()==0){
//                    txtStr=FlyTextUtil.readFile(FlyTextUtil.SDPATH,FlyTextUtil.SUBMQTT);
//                }else {
//                    txtStr=FlyTextUtil.readFile(sdPath,FlyTextUtil.SUBMQTT);
//                }
                String deviceSn=PreferenceUtil.getString(PreferenceUtil.DEVICESN,"intefly");
                String txtStr=FlyTextUtil.readFile(FlyTextUtil.SDPATH,FlyTextUtil.SUBMQTT);
                Log.e(TAG, "onSuccess: 订阅的内容为="+txtStr);
                //如果sn号和设备之前的号码一样，则去判断有没有订阅文本。不然直接订阅一次，这样子避免设备sn重新烧录不一样号码的时候出现因为有文本不订阅的情况
                if (FlyUtil.getSn(SocketService.this).equals(deviceSn) && txtStr.length()>7 && txtStr.substring(0,7).equals("private") ){
                    String[] serverTopics=txtStr.split("/");
                    subscribeTopic(serverTopics,txtStr);
                }else {
                    mqttAndroidClient.subscribe(responseTopics,qoss);
                    Log.i(TAG, "onSuccess: 设备订阅成功之后，上传一条信息" );
                    //如果没有相关订阅消息，则提醒服务器给一条
                    String topic=RESPONSE_TOPIC;
                    Integer qos=2;
                    Boolean retained=false;
                    mqttAndroidClient.publish(topic,FlyUtil.getSn(SocketService.this).getBytes(),qos.intValue(),retained.booleanValue());
                    Log.i(TAG, "onSuccess: 设备上传信息之后" );
                }

                //在这里进行一次数据同步
                if (isOnlyOneDo){
                    isOnlyOneDo=false;
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            //延时3s进行广告内容同步
                            try {
                                Thread.sleep(3000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            sendContent(ActivityConfig.syncaddata,"0");
                        }
                    }).start();

                }
//                mqttAndroidClient.subscribe(RESPONSE_TOPIC,2);//订阅主题，参数：主题，服务质量

            }catch (MqttException e){
                e.printStackTrace();
                Log.i(TAG, "onSuccess: 设备连接陈工之后上传信息出现问题"+e.getMessage() );
            }
        }

        @Override
        public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
            exception.printStackTrace();
            Log.i(TAG, "mqtt设备重新连接失败++++"+exception.getLocalizedMessage() );
//            if (!isConnecting){
//                doClientConnection();//重连接
//            }

        }
    };


    boolean isTxt=false;

    SerialHelper ledSc;    //485 环监、路灯、电量，RS485 通讯
    SerialHelper ttyS0;    //串口
    SerialHelper waterSc;    //串口  水位
    SerialHelper angalSc;    //串口  角度倾斜检测，充电，TTL 串口通讯
//    DispQueueThread DispQueue;
    boolean serialFlag=true;//用于关闭它
    /**
     *=============================串口数据获取和处理============================
     */
    //----------------------------------------
//    public class SerialControl extends SerialHelper {
//
//        public SerialControl(){
//        }
//
//        @Override
//        protected void onDataReceived(final ComBean ComRecData)
//        {
//            DispQueue.AddQueue(ComRecData);
//        }
//    }
    //----------------------------------------------------
//    private class DispQueueThread extends Thread{
//        private Queue<ComBean> QueueList = new LinkedList<ComBean>();
//        @Override
//        public void run() {
//            super.run();
//            Log.i(TAG, "runddddd: "+DispQueue.getName() );
//            while(serialFlag && !isInterrupted()) {
//                final ComBean ComData;
//                while((ComData=QueueList.poll())!=null)
//                {
////                    DispRecData(ComData);
//                    try {
//                        Thread.sleep(100);
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                    break;
//                }
//            }
//        }
//
//        public synchronized void AddQueue(ComBean ComData){
//            Log.e(TAG, "AddQueue: 收到串口的数据，添加了" );
//            QueueList.add(ComData);
//        }
//    }

    Map<String,String> waterMap=new HashMap<>();

    private String receiveStr=null;
    private String length64Data="";
    //------------------------------------接收从串口过来的数据,然后发送到服务器
    private static boolean isOnly=false;
    Map<String,String> sensorMap;//将所有待上传的数据进行添加进入里面，减少json的编写

    private Map<String,String> getSensorMap(){
        if (sensorMap==null){
            sensorMap=new HashMap<>();
        }
        return sensorMap;
    }
    //    private boolean isFirst=true;
    private String message;
    private StringBuilder sbStr=new StringBuilder();
    String controlStr;
    private void DispRecData(final ComBean ComRecData){


        if (angalserial.equals(ComRecData.sComPort) | led485serial.equals(ComRecData.sComPort) | water485serial.equals(ComRecData.sComPort)){
//            message=(new String(ComRecData.bRec)).toString();
            message= MyFunc.ByteArrToHex(ComRecData.bRec);
        }

        /**
         * 串口过来的数据进行解析
         */
        if (water485serial.equals(ComRecData.sComPort)){
            //初步定义这个连接控制器
            sendOrderInt=10; //数据到这里即表明有数据返回，则可以马上进行下一条数据下发
//            Log.i(TAG, "DispRecData:ttyS1 "+message );
            String receive= message.replace(" ","");
            receive=length64Data+receive;
            Log.i(TAG, "DispRecData: 洗狗机ttys4下发指令返回来的数据="+receive+";数据长度="+receive.length() );
            if (receive.length()>5){
                Log.e(TAG, "DispRecData: 洗狗机返回有用值="+receive.substring(0,receive.length()-4));
                Log.e(TAG, "DispRecData: 洗狗机返回没有用值="+receive.substring(receive.length()-4));
                byte[] inputb=HexToByteUtil.hexString2Bytes(receive.substring(0,receive.length()-4));
                short src1= CRCFromCUtil.getCRCData(inputb,inputb.length);
                String crc16=String.format("%04X",Integer.valueOf(src1));
                Log.e("TAG", "onClick: 获取到的Hex值为="+crc16 );
                if (crc16.length()>4){
                    crc16=crc16.substring(crc16.length()-4);
                }
                if (crc16.equals(receive.substring(receive.length()-4))){
                    //CRC解码成功
                    Log.e(TAG, "DispRecData: 洗狗机将返回值CRC解码成功="+crc16 );

                    if (receive.length()==34){
                        double negative=-1d;
//                String waterTem=receive.substring(6,10);
//                String invirTem=receive.substring(10,14);
//                String light=receive.substring(14,18);
//                String doorState=receive.substring(18,22);
//                String urgenState=receive.substring(22,26);
//                String waterLevel=receive.substring(26,30);
                        double waterTemInt =Integer.parseInt(receive.substring(7,10),16)/10.0d;
                        if (receive.substring(6,7).equals("8")){
                            waterTemInt=waterTemInt*negative;
                        }
                        this.waterTemInt=waterTemInt;
                        double invirTemInt=Integer.parseInt(receive.substring(11,14),16)/10.0d;
                        if (receive.substring(10,11).equals("8")){
                            invirTemInt=invirTemInt*negative;
                        }
                        this.invirTemInt=invirTemInt;
                        boolean doorStateFlag=false;
                        if ("00FF".equals(receive.substring(18,22))){
                            //关门状态
                            doorStateFlag=true;
                            doorStr="Close";
                        }else{
                            doorStr="Open";
                        }

                        boolean urgenStateFlag=true;
                        if ("00FF".equals(receive.substring(22,26))){
                            //急停
                            urgenStateFlag=false;
                        }

                        boolean waterLevelFlag=true;
                        if ("00FF".equals(receive.substring(26,30))){
                            //水位异常
                            waterLevelFlag=false;
                        }
                        if (iServiceToActivity!=null){
                            iServiceToActivity.showDogBoxState(waterTemInt,invirTemInt,doorStateFlag,urgenStateFlag,waterLevelFlag);
                        }

                    }else if (receive.length()==16){
                        //01 06 00 03 00 AA F9 B5
                        sendContent(ActivityConfig.SHOWBACK,receive);
                    }else if (receive.length()==94){
                        double negative=-1d;
//                String waterTem=receive.substring(6,10);
//                String invirTem=receive.substring(10,14);
//                String light=receive.substring(14,18);
//                String doorState=receive.substring(18,22);
//                String urgenState=receive.substring(22,26);
//                String waterLevel=receive.substring(26,30);
                        //水温
                        double waterTemInt =Integer.parseInt(receive.substring(7,10),16)/10.0d;
                        if (receive.substring(6,7).equals("8")){
                            waterTemInt=waterTemInt*negative;
                        }
                        this.waterTemInt=waterTemInt;
                        //室内温度
                        double invirTemInt=Integer.parseInt(receive.substring(11,14),16)/10.0d;
                        if (receive.substring(10,11).equals("8")){
                            invirTemInt=invirTemInt*negative;
                        }
                        this.invirTemInt=invirTemInt;
                        //开关门状态
                        boolean doorStateFlag=false;
                        if ("00FF".equals(receive.substring(18,22))){
                            //关门状态
                            doorStateFlag=true;
                            doorStr="Close";
                        }else{
                            doorStr="Open";
                        }
                        //紧急按钮状态
                        boolean urgenStateFlag=true;
                        if ("00FF".equals(receive.substring(22,26))){
                            //急停
                            urgenStateFlag=false;
                        }
                        //水位状态
                        boolean waterLevelFlag=true;
                        if ("00FF".equals(receive.substring(26,30))){
                            //水位异常
                            waterLevelFlag=false;
                        }
                        //沐浴露状态
                        boolean bodyWashFlag=true;
                        if ("00FF".equals(receive.substring(30,34))){
                            //沐浴露异常
                            bodyWashFlag=false;
                        }
                        //护毛素状态
                        boolean conditionerFlag=true;
                        if ("00FF".equals(receive.substring(34,38))){
                            //护毛素异常
                            conditionerFlag=false;
                        }
                        //护毛素状态
                        boolean disinfectantFlag=true;
                        if ("00FF".equals(receive.substring(38,42))){
                            //护毛素异常
                            disinfectantFlag=false;
                        }
                        //用水量
                        double waterUse=Integer.parseInt(receive.substring(42,46),16)/10.0d;
                        //用电量
                        double elecUse=Integer.parseInt(receive.substring(46,50),16)/10.0d;
                        //高压水泵电流
                        double elecPumpCurrent=Integer.parseInt(receive.substring(50,54),16)/10.0d;
                        //风干加热电流
                        double elecHeatingCurrent=Integer.parseInt(receive.substring(54,58),16)/10.0d;
                        //旋涡风机电流
                        double elecVortexCurrent=Integer.parseInt(receive.substring(58,62),16)/10.0d;
                        //换气风机电流
                        double elecAirCurrent=Integer.parseInt(receive.substring(62,66),16)/10.0d;
                        //液体泵电流
                        double elecLiquidCurrent=Integer.parseInt(receive.substring(66,70),16)/10.0d;
                        //水泵阀门电流
                        double elecWaterPumpCurrent=Integer.parseInt(receive.substring(70,74),16)/10.0d;
                        //沐浴露阀门电流
                        double elecBodyWashCurrent=Integer.parseInt(receive.substring(74,78),16)/10.0d;
                        //护毛素阀门电流
                        double elecConditionerCurrent=Integer.parseInt(receive.substring(78,82),16)/10.0d;
                        //消毒液阀门电流
                        double elecDisinfectantCurrent=Integer.parseInt(receive.substring(82,86),16)/10.0d;
                        //门锁电流
                        double elecDoorCurrent=Integer.parseInt(receive.substring(86,90),16)/10.0d;
                        if (iServiceToActivity!=null){
                            iServiceToActivity.showDogBoxState(waterTemInt,invirTemInt,doorStateFlag,urgenStateFlag,waterLevelFlag,
                                    bodyWashFlag,conditionerFlag,disinfectantFlag,waterUse,elecUse,elecPumpCurrent,elecHeatingCurrent,
                                    elecVortexCurrent,elecAirCurrent,elecLiquidCurrent,elecWaterPumpCurrent,elecBodyWashCurrent,elecConditionerCurrent,
                                    elecDisinfectantCurrent,elecDoorCurrent);
                        }
                    }
                    length64Data="";
                }else if (receive.length()==64){
                    //说明这条数据还未全部下来，需要继续获取
                    length64Data=receive;
                }else{
                    //说明这条数据是有问题的
                    length64Data="";
                }


            }


        }else if (angalserial.equals(ComRecData.sComPort)){
            //初步定义这个连接控制器
//            Log.i(TAG, "DispRecData:angalSc "+message );
            String receive= message.replace(" ","");
            Log.i(TAG, "DispRecData: ttys5回来的数据="+receive );
            if (receive.length()==22){

            }


        }else if (led485serial.equals(ComRecData.sComPort)){
//初步定义这个连接控制器
//            Log.i(TAG, "DispRecData:ledSc "+message );

//            01 03 14 00 00 00 00 00 02 00 5A 01 C9 00 D8 01 BB 00 19 00 24 03 FF FB DB
            //01 03 14 01 D0 00 A9 01 E7 00 1C 00 22 04 01 00 00 00 00 03 2A 02 5E CC BB
            Log.i(TAG, "气象数据获取 传感器 DispRecData: ttyS8"+message );
            String str= message.replace(" ","");
            if (str.length()==64){
                receiveStr=str;
            }else if (receiveStr!=null){
                receiveStr=receiveStr+str;
            }





            /***********************************分开来的百叶盒和风速风向***********************************/



        }

    }

    /**
     *
     * @param dogboxStateInt  洗狗机当前状态 洗狗中，消毒中，空闲中
     * @param leftTime 还有多久可以进行扫码进行下一次流程  分钟
     */
    public void setDogStatus(int dogboxStateInt,int leftTime){
        this.dogboxStateInt=dogboxStateInt;
        this.dogLeaveTime=leftTime;
        Log.e(TAG, "setDogStatus: 上传的状态值为="+dogboxStateInt+";剩余的时间是="+leftTime );
    }



    //----------------------------------------------------发送信息到单片机上面
    private void sendPortData(SerialHelper ComPort,String sOut){
        if (sOut.contains(SerialConfigUtil.CONFIGDOGBOXSTATUS) || sOut.contains(SerialConfigUtil.CONFIGDOGBOXSTATUS2)){
            Log.i(TAG, "sendPortData:下发状态指令 ComPort="+ComPort.getPort()+";order="+sOut+";串口是否打开="+ComPort.isOpen()+";isTxt="+isTxt);
        }else{
            Log.e(TAG, "sendPortData: 下发命令指令 order="+sOut );
        }

        //在这里添加这个好像有问题，会造成重复启动串口 使用serial_port查看串口启动日志
//        if (!ComPort.isOpen()){
//            try {
//                ComPort.close();
//                ComPort.open();
//            } catch (IOException e) {
//                throw new RuntimeException(e);
//            }
//        }
        if (ComPort!=null && ComPort.isOpen())
        {
            for (int i = 0; i < sOut.length(); i++) {
                if (!isHex(sOut.substring(i,i+1)))
                {
//                    Log.i(TAG, "sendPortData: 直接返回？" );
                    Log.e(TAG, "sendPortData: 下发指令监测指令是否出现了16进制问题" );
                    return;
                }
            }

            if (isTxt)
            {
                ComPort.sendTxt(sOut);
            }else {
               Log.e(TAG, "sendPortData: 向串口下发了数据" );
                ComPort.sendHex(sOut);
            }
        }
//        Log.e(TAG, "sendPortData: 下发指令="+ComPort.isOpen());
    }

    private boolean isHex(String str)
    {
        switch (str)
        {
            case "f":
            case "F":
            case "e":
            case "E":
            case "d":
            case "D":
            case "c":
            case "C":
            case "b":
            case "B":
            case "a":
            case "A":
            case "9":
            case "8":
            case "7":
            case "6":
            case "5":
            case "4":
            case "3":
            case "2":
            case "1":
            case "0":
            case "":
                return true;
            default:
                return false;
        }
    }

    //----------------------------------------------关闭串口
    private void CloseComPort(SerialHelper ComPort){
        if (ComPort!=null){
            ComPort.stopSend();
            ComPort.close();
        }
    }
    //----------------------------------------------------
//    private void OpenComPort(SerialHelper ComPort){
//        try
//        {
//            if (!ComPort.isOpen()){
//                ComPort.openSerial();
//            }
//        } catch (SecurityException e) {
//            Log.i(TAG, "OpenComPort: "+e.getMessage());
//        } catch (IOException e) {
//            Log.i(TAG, "OpenComPort: "+e.getMessage());
//        } catch (InvalidParameterException e) {
//            Log.i(TAG, "OpenComPort: "+e.getMessage());
//        }
//    }

    public boolean isAlreadyConnected() {
        if(mqttAndroidClient != null){
            try{
                boolean result = mqttAndroidClient.isConnected();
                if(result){
                    return true;
                }
                else {
                    return false;
                }
            }
            catch (Exception e){
                e.printStackTrace();
                return false;
            }
        }
        else {
            return false;
        }
    }



    @Override
    public boolean onUnbind(Intent intent) {
        //关闭串口
//        CloseComPort(ttyS0);
//        CloseComPort(waterSc);
//        CloseComPort(angalSc);
//        CloseComPort(ledSc);
        waterSc.close();
        angalSc.close();
        ledSc.close();
        return super.onUnbind(intent);
    }


    private synchronized void getAdvert(String adstr,String upDateTime){
        Log.i(TAG, "messageArrived: 广告"+adstr );
        //需要解析和主界面操作的，全部发过去。让主界面进行处理 广告解析
        String uptime=upDateTime;
        PreferenceUtil.commitString(PreferenceUtil.SYNCAD,uptime);
        List<AlarmBean> alarmBeanList=new Gson().fromJson(adstr,new TypeToken<List<AlarmBean>>(){}.getType());
        if (iServiceToActivity!=null){
            iServiceToActivity.sendAdvert(alarmBeanList);
        }
    }


    public void closeAllSwitch(){

        //关水阀
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXWATERCLOSE);
        //水箱加热关
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXWATERHEATINGCLOSE);
        //高压水泵阀门关
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXWATERPUMPCLOSE);
        //沐浴露阀门关
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXWASHCLOSE);
        //浓缩液泵阀门关
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXCONCENTRATEDCLOSE);
        //护毛素泵阀门关
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXCONDITIONERCLOSE);
        //风机加热条关
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXHEATINGCLOSE);
        //吹风机关
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXHAIRDRYERCLOSE);
        //消毒液关
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXDISINFECTANTCLOSE);
        //内照明关
        sendMechineOrder(SerialConfigUtil.CONFIGDOGBOXLIGHTCLOSE);
        //换气风机关
        sendMechineOrder(SerialConfigUtil.SendHex26);

    }

    @Override
    public void onDestroy() {
        Log.e("tiwolf", "uncaughtException: SocketService--收集到app遭遇到未知错误，清除缓存，异常线程 出现线程正常结束的情况" );

        try{
            closeAllSwitch();
        }catch (Exception e){
            e.printStackTrace();
        }


        serialFlag=false;
        busy=false;
        dogBoxExitFlag=false;
        conMqttFlag=false;
        //mqtt断开连接
        try {
            if (mqttAndroidClient!=null){
//                if (mqttAndroidClient.isConnected()){
//                    mqttAndroidClient.disconnect();//断开连接
//                }
                mqttAndroidClient.disconnect();
//                mqttAndroidClient.unregisterResources();
            }
//            mqttAndroidClient.close();

            Log.i(TAG, "publish: 这个挂掉了？" );
//            timerHelp.cancel();
//            timerHelp=null;

        }catch (MqttException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }

        try {
            if (dogSerialThread != null) {
                dogSerialThread.interrupt();
                try {
                    dogSerialThread.join();
                } catch (InterruptedException e) {
                    dogSerialThread.interrupt();
                }
                dogSerialThread = null;
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        waterSc.close();
        angalSc.close();
        ledSc.close();
//        CloseComPort(waterSc);
//        CloseComPort(angalSc);
//        CloseComPort(ledSc);

        SingleThreadPool.unInit();
        super.onDestroy();
    }

    IServiceToActivity iServiceToActivity;
    /**
     * 直接搞个接口传值吧
     *
     */
    public interface  IServiceToActivity{
        void sendMsgToActivity(String key,Object value,String time);
        void sendMsgToActivity(String key,Object value);
        void sendAdvert(List<AlarmBean> alarmBeanList);
        void showDogBoxState(double water,double invir,boolean doorStateFlag,boolean urgenStateFlag,boolean waterLevelFlag);
        void showDogBoxState(double water,double invir,boolean doorStateFlag,boolean urgenStateFlag,boolean waterLevelFlag,
                             boolean bodyWashFlag,boolean conditionerFlag,boolean disinfectantFlag,double waterUse,double elecUse,double elecPumpCurrent,double elecHeatingCurrent,
                             double elecVortexCurrent,double elecAirCurrent,double elecLiquidCurrent,double elecWaterPumpCurrent,double elecBodyWashCurrent,double elecConditionerCurrent,
                             double elecDisinfectantCurrent,double elecDoorCurrent);
        void showBackMechineOrder(String receiveOrder);
        void showNetworkState(boolean flag);
    }

    public void setIService(IServiceToActivity iService){
        this.iServiceToActivity=iService;
    }

    private void sendContent(String key,String value){
        if (iServiceToActivity!=null){
            iServiceToActivity.sendMsgToActivity(key,value);
        }
    }
}
